package DrawCard

import (
	codecs "sanguo/codec/cs"
	"sanguo/node/common/DropPool"
	"sanguo/node/common/com_type"
	"sanguo/node/common/transaction"
	"sanguo/node/node_game"
	"sanguo/node/node_game/module/role"
	"sanguo/node/node_game/user"
	table_DrawCard "sanguo/node/table/excel/table/DrawCard"
	table_GamePlay "sanguo/node/table/excel/table/GamePlay"
	table_Store "sanguo/node/table/excel/table/Store"
	cs_message "sanguo/protocol/cs/message"
	"time"

	"github.com/golang/protobuf/proto"
)

type transactionDrawCard struct {
	transaction.TransactionBase
	user    *user.User
	req     *codecs.Message
	resp    *cs_message.DrawCardToC
	errcode cs_message.EnumType
}

func (this *transactionDrawCard) GetModuleName() string {
	return "DrawCard"
}

func (this *transactionDrawCard) GetReplyMsg() proto.Message {
	return &cs_message.DrawCardToC{}
}

func (this *transactionDrawCard) SetExpiredTime(expired time.Time) {
	this.Expired = expired
}

func (this *transactionDrawCard) GetExpiredTime() time.Time {
	return this.Expired
}

func (this *transactionDrawCard) Begin() {

	this.resp = &cs_message.DrawCardToC{}
	msg := this.req.GetData().(*cs_message.DrawCardToS)
	roleModule := this.user.GetModuleByName("role").(*role.RoleModule)
	role := roleModule.CurrentRole()

	if nil == role || !role.IsRoleModleData() {
		node_game.Infoln(role.GetUserID(), role.GetID(), "role is nil")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}
	node_game.Infof("%s %d Call DrawCard type:%d times:%d", role.GetUserID(), role.GetID(), msg.GetCardType(), msg.GetDrawTimes())

	//验证功能开启
	if role.GetLev() < table_GamePlay.Table_.IDMap[com_type.GamePaly_DrawCard].UnlockLevel {
		node_game.Infoln(role.GetUserID(), role.GetID(), " fail DrawCard System is not Unlock")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	DCDef := table_DrawCard.Table_.IDMap[msg.GetCardType()]
	if DCDef == nil {
		node_game.Infoln(role.GetUserID(), role.GetID(), "DrawCard fail : DCDef is nil ")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	drawCard := role.GetRoleDrawCard().GetDrawCard(msg.GetCardType())
	if drawCard == nil || msg.GetDrawTimes() <= 0 {
		node_game.Infoln(role.GetUserID(), role.GetID(), "DrawCard fail : drawCard is nil or msg Times is fail")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	/*
	* 在store表中 查找消耗的道具ID
	 */
	goods := table_Store.Table_.IDMap[DCDef.StoreID]
	if goods == nil {
		node_game.Infoln(role.GetUserID(), role.GetID(), "DrawCard fail : goods is nil")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	item := role.GetRoleItem().GetItem(goods.ItemID)
	if item == nil || item.ItemCount < msg.GetDrawTimes()*DCDef.CostCount {
		node_game.Infoln(role.GetUserID(), role.GetID(), "DrawCard fail : count not enough")
		this.errcode = cs_message.EnumType_ERROR
		this.user.EndTrans(this)
		return
	}

	transfromWeapons := map[int32]int32{}
	awardsMap := role.GetRoleDrawCard().PlayerDrawCard(msg.GetCardType(), msg.GetDrawTimes())
	awards := []*DropPool.Award{}
	for _, a := range awardsMap {
		if a != nil {
			awards = append(awards, a)
			this.resp.Awards = append(this.resp.Awards, DropPool.PackAward(a))
			for _, v := range a.Infos {
				if v.Type == com_type.Drop_Weapon {
					weapon := role.GetRoleWeapon().GetWeapon(v.ID)
					if weapon != nil {
						if _, ok := transfromWeapons[v.ID]; ok {
							transfromWeapons[v.ID]++
						} else {
							transfromWeapons[v.ID] = 1
						}
					}
				}
			}
		}
	}
	for weaponId, count := range transfromWeapons {
		this.resp.Weapons = append(this.resp.Weapons, &cs_message.TransfromWeapon{
			WeaponId: proto.Int32(weaponId),
			Count:    proto.Int32(count),
		})
	}

	role.GiveOutAward(DropPool.PackAwardsToOne(awards))

	//变动更新
	drity := &cs_message.RoleDrawCardToC{
		DrawCards: role.GetRoleDrawCard().PackModify(),
	}
	this.user.Post(drity)

	role.GetRoleItem().UseItem(goods.ItemID, DCDef.CostCount*msg.GetDrawTimes())
	role.OnItemDirty()

	node_game.Infoln(role.GetUserID(), role.GetID(), "DrawCard OK")
	this.errcode = cs_message.EnumType_OK
	this.user.EndTrans(this)
}

func (this *transactionDrawCard) End() {
	this.resp.Errcode = cs_message.EnumType(this.errcode).Enum()
	this.user.Reply(this.req.GetSeriNo(), this.resp)
}

func (this *transactionDrawCard) Timeout() {
	this.resp.Errcode = cs_message.EnumType(cs_message.EnumType_RETRY).Enum()
	this.user.EndTrans(this)
}

func init() {
	user.RegisterTransFunc(&cs_message.DrawCardToS{}, func(user *user.User, msg *codecs.Message) transaction.Transaction {
		return &transactionDrawCard{
			user: user,
			req:  msg,
		}
	})
}
